#include "outputCtl.h"
#include "chargeCtrl.h"	//extern timeoutCalc(uint32_t,uint32_t)




typedef struct 
{
	
	relayTypeDefe relayTypeEventId;					//relay run event
	uint8_t setRunFlag;								//set  run status  0 don't runing ,  1 runing
	uint8_t setRelayStatus;							//relay io status
	uint8_t setRelayCycleStatus;					//relay cyclye status
	uint8_t synchronizationTimeFlag;				//synchronization Time Flag
	uint32_t execCloseDelayTime;					//relay turn on delay time  
	uint32_t execDisconnectDelayTime;				//relay turn off delay time
	uint32_t Pin; 									// GPIO pin
	GPIO_TypeDef* GPIOx;							// GPIO group
	relayCtrlPtrFuncdef relayCtrlFuncCallback;		// callback time
	
}outputCtrlRelayDef;




outputCtrlRelayDef outputCtrlRelay[] = 
{
	//    event id       |    relay run event  |set run status
	{	AC_CONTROL_MODULE,				0,			0,			0,			0,	    0,	10000,		AC_CONTROL_CTL_Pin,				AC_CONTROL_CTL_Port,				outputCtrlCallback},
	{	FAN_MODULE		,				0,			0,			0,			0,	  	0,		0,		FAN_CTL_1_Pin,					FAN_CTL_1_Port,						outputCtrlCallback},
	{	A_RED_LIGHT_MODULE,				0,			0,			0,	  		0,	 1000,	 1000,		A_RED_LIGHT_CTL_Pin,			A_RED_LIGHT_CTL_Port,				outputCtrlCallback},
	{	A_GREEN_LIGHT_MODULE,			0,			0,			0,	  		0,	 1000,	 1000,		A_GREEN_LIGHT_CTL_Pin,			A_GREEN_LIGHT_CTL_Port,				outputCtrlCallback},
	{	A_BLUE_LIGHT_MODULE,			0,			0,			0,	  		0,	 1000,	 1000,		A_BLUE_LIGHT_CTL_Pin,			A_BLUE_LIGHT_CTL_Port,				outputCtrlCallback},
	{	A_DC_CONTACTOR1_MODULE,			0,			0,			0,			0,		0,		0,		A_DC_CONTACTOR1_CTL_Pin,		A_DC_CONTACTOR1_CTL_Port,			outputCtrlCallback},
	{	A_DC_CONTACTOR2_MODULE,			0,			0,			0,			0,		0,		0,		A_DC_CONTACTOR2_CTL_Pin,		A_DC_CONTACTOR2_CTL_Port,			outputCtrlCallback},
	{	A_DC_CONTACTOR3_MODULE,			0,			0,			0,			0,		0,		0,		A_DC_CONTACTOR3_CTL_Pin,		A_DC_CONTACTOR3_CTL_Port,			outputCtrlCallback},
	{	A_NG_CTL_MODULE,				0,			0,			0,			0,		0,		0,		A_NG_CTL_Pin,					A_NG_CTL_Port,						outputCtrlCallback},
	{	A_PG_CTL_MODULE,				0,			0,			0,			0,		0,		0,		A_PG_CTL_Pin,					A_PG_CTL_Port,						outputCtrlCallback},
	{	A_AUXILIARY_POWER_MODULE,		0,			0,			0,			0,		0,		0,		A_AUXILIARY_POWER_CTL_Pin,		A_AUXILIARY_POWER_CTL_Port,			outputCtrlCallback},
	{	A_ELECTRONIC_LOCK_MODULE,		0,			0,			0,			0,		0,		0,		A_ELECTRONIC_LOCK_CTL_Pin,		A_ELECTRONIC_LOCK_CTL_Port,			outputCtrlCallback},
	{	B_RED_LIGHT_MODULE,				0,			0,			0,	  		0,	 1000,	 1000,		B_RED_LIGHT_CTL_Pin,			B_RED_LIGHT_CTL_Port,				outputCtrlCallback},
	{	B_GREEN_LIGHT_MODULE,			0,			0,			0,	  		0,	 1000,	 1000,		B_GREEN_LIGHT_CTL_Pin,			B_GREEN_LIGHT_CTL_Port,				outputCtrlCallback},
	{	B_BLUE_LIGHT_MODULE,			0,			0,			0,			0,	 1000,	 1000,		B_BLUE_LIGHT_CTL_Pin,			B_BLUE_LIGHT_CTL_Port,				outputCtrlCallback},
	{	B_DC_CONTACTOR1_MODULE,			0,			0,			0,			0,		0,		0,		B_DC_CONTACTOR1_CTL_Pin,		B_DC_CONTACTOR1_CTL_Port,			outputCtrlCallback},
	{	B_DC_CONTACTOR2_MODULE,			0,			0,			0,			0,		0,		0,		B_DC_CONTACTOR2_CTL_Pin,		B_DC_CONTACTOR2_CTL_Port,			outputCtrlCallback},
	{	B_DC_CONTACTOR3_MODULE,			0,			0,			0,			0,		0,		0,		B_DC_CONTACTOR3_CTL_Pin,		B_DC_CONTACTOR3_CTL_Port,			outputCtrlCallback},
	{	B_NG_CTL_MODULE,				0,			0,			0,			0,		0,		0,		B_NG_CTL_Pin,					B_NG_CTL_Port,						outputCtrlCallback},
	{	B_PG_CTL_MODULE,				0,			0,			0,			0,		0,		0,		B_PG_CTL_Pin,					B_PG_CTL_Port,						outputCtrlCallback},
	{	B_AUXILIARY_POWER_MODULE,		0,			0,			0,			0,		0,		0,		B_AUXILIARY_POWER_CTL_Pin,		B_AUXILIARY_POWER_CTL_Port,			outputCtrlCallback},
	{	B_ELECTRONIC_LOCK_MODULE,		0,			0,			0,			0,		0,		0,		B_ELECTRONIC_LOCK_CTL_Pin,		B_ELECTRONIC_LOCK_CTL_Port,			outputCtrlCallback},
	{	A_CHADEMO_LOCK_MODULE,			0,			0,			0,			0,		0,		0,		A_CHADEMO_LOCK_Pin,				A_CHADEMO_LOCK_Port,				outputCtrlCallback},
	{	A_CHADEMO_D1_MODULE,			0,			0,			0,			0,		0,		0,		A_CHADEMO_D1_Pin,				A_CHADEMO_D1_Port,					outputCtrlCallback},
	{	A_CHADEMO_D2_MODULE,			0,			0,			0,			0,		0,		0,		A_CHADEMO_D2_Pin,				A_CHADEMO_D2_Port,					outputCtrlCallback},
	{	B_CHADEMO_LOCK_MODULE,			0,			0,			0,			0,		0,		0,		B_CHADEMO_LOCK_Pin,				B_CHADEMO_LOCK_Port,				outputCtrlCallback},
	{	B_CHADEMO_D1_MODULE,			0,			0,			0,			0,		0,		0,		B_CHADEMO_D1_Pin,				B_CHADEMO_D1_Port,					outputCtrlCallback},
	{	B_CHADEMO_D2_MODULE,			0,			0,			0,			0,		0,		0,		B_CHADEMO_D2_Pin,				B_CHADEMO_D2_Port,					outputCtrlCallback},
	{	BOARD_LED_RUN_MODULE,			0,			0,			0,			0,		0,		0,		BOARD_LED_RUN_Pin,				BOARD_LED_RUN_Port,					outputCtrlCallback},
	{	BOARD_LED_FALUT_MODULE,			0,			0,			0,			0,		0,		0,		BOARD_LED_FALUT_Pin,			BOARD_LED_FALUT_Port,				outputCtrlCallback}
	
};




__weak void  outputCtrlCallback(void)
{
	//do nothing
}

/**********************************************************************************************************************************************
* Function  : setKeyValueHandle
*
*
* Parameter   evenID   status
* 
*
* return :    None
**********************************************************************************************************************************************/
void setKeyValueHandle(relayTypeDefe eventID ,uint8_t status,uint8_t cycleStatus,uint32_t CloseDelayTime,uint32_t disconnectDelayTime,relayCtrlPtrFuncdef relayCtrlFuncCallback)
{
	
	if(eventID < RELAYCTRLTYPEMAX)
	{
		outputCtrlRelay[eventID].setRunFlag = 1;
		outputCtrlRelay[eventID].synchronizationTimeFlag = 1;
		outputCtrlRelay[eventID].setRelayStatus = status;
		if(CloseDelayTime != 0x00000000)
		{
			outputCtrlRelay[eventID].execCloseDelayTime = CloseDelayTime;
		}
		if(disconnectDelayTime != 0x00000000)
		{
			outputCtrlRelay[eventID].execDisconnectDelayTime = disconnectDelayTime;
		}
		outputCtrlRelay[eventID].setRelayCycleStatus = cycleStatus;
		outputCtrlRelay[eventID].relayCtrlFuncCallback = relayCtrlFuncCallback;
	}
}

uint8_t getKeyValueHandle(relayTypeDefe eventID)
{
	uint8_t keyStatus = 0;
	keyStatus = HAL_GPIO_ReadPin(outputCtrlRelay[eventID].GPIOx, outputCtrlRelay[eventID].Pin);
	return keyStatus;
}

//get the setting value of relay status  0:open	1:close
uint8_t getRelaySettingStatus(relayTypeDefe eventID)
{
	return outputCtrlRelay[eventID].setRelayStatus;
}


/**********************************************************************************************************************************************
* Function  : setKeyValueHandle
* 
*
* Parameter   evenID   status
* 
*
* returl :    None
**********************************************************************************************************************************************/
void outputRelayEntry(void)
{
	uint8_t i;
	static uint32_t delayDisConnectOperation[32] = {0x00};
	static uint32_t delayCloseOperation[32] = {0x00};
	static uint8_t convertFlag[32] = {0x00};
	
	for(i = 0;i < RELAYCTRLTYPEMAX; i ++)
	{
		if(outputCtrlRelay[i].setRunFlag == 1)
		{
			if(outputCtrlRelay[i].synchronizationTimeFlag == 1)
			{
				delayDisConnectOperation[i] = HAL_GetTick();
				delayCloseOperation[i] = HAL_GetTick();
				outputCtrlRelay[i].synchronizationTimeFlag = 0;
			}
			if(outputCtrlRelay[i].setRelayStatus == 1)
			{
				if(outputCtrlRelay[i].execCloseDelayTime > 0)
				{
					if(timeoutCalc(delayCloseOperation[i],outputCtrlRelay[i].execCloseDelayTime))
					{
						HAL_GPIO_WritePin(outputCtrlRelay[i].GPIOx, outputCtrlRelay[i].Pin, GPIO_PIN_SET);
						if(outputCtrlRelay[i].relayCtrlFuncCallback != NULL)
						{
							outputCtrlRelay[i].relayCtrlFuncCallback();
						}
						outputCtrlRelay[i].setRunFlag = 0;			
					}
				}
				else
				{
					HAL_GPIO_WritePin(outputCtrlRelay[i].GPIOx, outputCtrlRelay[i].Pin, GPIO_PIN_SET);
					if(outputCtrlRelay[i].relayCtrlFuncCallback != NULL)
					{
						outputCtrlRelay[i].relayCtrlFuncCallback();
					}
					outputCtrlRelay[i].setRunFlag = 0;
				}
			}
			else if(outputCtrlRelay[i].setRelayStatus == 0)
			{				
				if(outputCtrlRelay[i].execDisconnectDelayTime > 0)
				{
					if(timeoutCalc(delayDisConnectOperation[i],outputCtrlRelay[i].execDisconnectDelayTime))
					{
						HAL_GPIO_WritePin(outputCtrlRelay[i].GPIOx, outputCtrlRelay[i].Pin, GPIO_PIN_RESET);
						if(outputCtrlRelay[i].relayCtrlFuncCallback != NULL)
						{
							outputCtrlRelay[i].relayCtrlFuncCallback();
						}
						outputCtrlRelay[i].setRunFlag = 0;
					}
				}
				else
				{
					HAL_GPIO_WritePin(outputCtrlRelay[i].GPIOx, outputCtrlRelay[i].Pin, GPIO_PIN_RESET);
					if(outputCtrlRelay[i].relayCtrlFuncCallback != NULL)
					{
						outputCtrlRelay[i].relayCtrlFuncCallback();
					}
					outputCtrlRelay[i].setRunFlag = 0;
				}
			}
		}
		//cycle process
		if(outputCtrlRelay[i].setRelayCycleStatus == 1)
		{
			if(outputCtrlRelay[i].synchronizationTimeFlag == 1)
			{
				delayDisConnectOperation[i] = HAL_GetTick();
				delayCloseOperation[i] = HAL_GetTick();
				outputCtrlRelay[i].synchronizationTimeFlag = 0;				
			}
			if(convertFlag[i] == 0)
			{
				if(outputCtrlRelay[i].execDisconnectDelayTime > 0)
				{
					if(timeoutCalc(delayDisConnectOperation[i],outputCtrlRelay[i].execDisconnectDelayTime))
					{
						delayCloseOperation[i] = HAL_GetTick();
						delayDisConnectOperation[i] = HAL_GetTick();
						HAL_GPIO_WritePin(outputCtrlRelay[i].GPIOx, outputCtrlRelay[i].Pin, GPIO_PIN_RESET);
						if(outputCtrlRelay[i].relayCtrlFuncCallback != NULL)
						{
							outputCtrlRelay[i].relayCtrlFuncCallback();
						}
						convertFlag[i] = 1;
					}
				}
			}
			else
			{
				if(timeoutCalc(delayCloseOperation[i], outputCtrlRelay[i].execCloseDelayTime))
				{
					delayDisConnectOperation[i] = HAL_GetTick();
					delayCloseOperation[i] = HAL_GetTick();
					HAL_GPIO_WritePin(outputCtrlRelay[i].GPIOx, outputCtrlRelay[i].Pin, GPIO_PIN_SET);
					if(outputCtrlRelay[i].relayCtrlFuncCallback != NULL)
					{
						outputCtrlRelay[i].relayCtrlFuncCallback();
					}
					convertFlag[i] = 0;
				}
			}
		}
	}
}



void outputTest(void)
{

	//	



	//setKeyValueHandle(A_RED_LIGHT_MODULE,0,1,0x00,0x00,NULL);
	//setKeyValueHandle(A_GREEN_LIGHT_MODULE,0,1,0x00,0x00,NULL);	
	//setKeyValueHandle(A_BLUE_LIGHT_MODULE,0,1,0x00,0x00,NULL);

	//setKeyValueHandle(B_RED_LIGHT_MODULE,0,1,0x00,0x00,NULL);
	//setKeyValueHandle(B_GREEN_LIGHT_MODULE,0,1,0x00,0x00,NULL);	
	//setKeyValueHandle(B_BLUE_LIGHT_MODULE,0,1,0x00,0x00,NULL);
		
		
		

	setKeyValueHandle(AC_CONTROL_MODULE,1,0,0x00,0x00,NULL);
	setKeyValueHandle(FAN_MODULE,1,0,0x00,0x00,NULL);


	setKeyValueHandle(A_DC_CONTACTOR1_MODULE,1,0,0x00,0x00,NULL);
	setKeyValueHandle(A_DC_CONTACTOR2_MODULE,1,0,0x00,0x00,NULL);
	setKeyValueHandle(A_DC_CONTACTOR3_MODULE,1,0,0x00,0x00,NULL);
	setKeyValueHandle(A_AUXILIARY_POWER_MODULE,1,0,0x00,0x00,NULL);
	setKeyValueHandle(A_ELECTRONIC_LOCK_MODULE,1,0,0x00,0x00,NULL);
	setKeyValueHandle(A_NG_CTL_MODULE,1,0,0x00,0x00,NULL);
	setKeyValueHandle(A_PG_CTL_MODULE,1,0,0x00,0x00,NULL);

	setKeyValueHandle(B_DC_CONTACTOR1_MODULE,1,0,0x00,0x00,NULL);
	setKeyValueHandle(B_DC_CONTACTOR2_MODULE,1,0,0x00,0x00,NULL);
	setKeyValueHandle(B_DC_CONTACTOR3_MODULE,1,0,0x00,0x00,NULL);
	setKeyValueHandle(B_AUXILIARY_POWER_MODULE,1,0,0x00,0x00,NULL);
	setKeyValueHandle(B_ELECTRONIC_LOCK_MODULE,1,0,0x00,0x00,NULL);
	setKeyValueHandle(B_NG_CTL_MODULE,1,0,0x00,0x00,NULL);
	setKeyValueHandle(B_PG_CTL_MODULE,1,0,0x00,0x00,NULL);



	setKeyValueHandle(A_CHADEMO_LOCK_MODULE,1,0,0x00,0x00,NULL);
	setKeyValueHandle(A_CHADEMO_D1_MODULE,1,0,0x00,0x00,NULL);
	setKeyValueHandle(A_CHADEMO_D2_MODULE,1,0,0x00,0x00,NULL);

	setKeyValueHandle(B_CHADEMO_LOCK_MODULE,1,0,0x00,0x00,NULL);
	setKeyValueHandle(B_CHADEMO_D1_MODULE,1,0,0x00,0x00,NULL);
	setKeyValueHandle(B_CHADEMO_D2_MODULE,1,0,0x00,0x00,NULL);



}
